// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
//
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.core.prefs.connectivity;

import java.io.BufferedInputStream;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

import org.dengues.commons.connectivity.IConnectivitySettingsConstants;
import org.dengues.commons.utils.DriverUtil;
import org.dengues.core.CorePlugin;
import org.dengues.core.ExceptionOperation;
import org.dengues.core.IDesignerCoreService;
import org.dengues.core.components.GlobalComponentNames;
import org.dengues.core.components.IXMLComponent;
import org.dengues.core.i18n.Messages;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 2007-11-25 qiang.zhang $
 * 
 */
public class ConnectivityManager {

    private static Connection connection;

    private static String schema;

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getConnection".
     * 
     * @param properties
     * @return
     */
    public static void getConnection(final Map properties) {
        connection = null;
        schema = (String) properties.get(EConnectivityProperties.PROP_ID_SCHEMA.getPropId());
        String rootpath = (String) properties.get(EConnectivityProperties.PROP_ID_ROOTPATH.getPropId());
        if (rootpath != null && !"".equals(rootpath)) { //$NON-NLS-1$
            System.setProperty("derby.system.home", rootpath); //$NON-NLS-1$
        }
        String[] jars = XMLFileManager.parseString((String) properties.get(IConnectivitySettingsConstants.PROP_DEFN_JARLIST));
        String dClass = (String) properties.get(EConnectivityProperties.PROP_ID_DRIVER.getPropId());
        try {
            Class clazz = DriverUtil.getDriverClassFromJars(jars, dClass);
            if (clazz == null) {
                clazz = Class.forName(dClass);
            }
            if (clazz != null) {
                Driver driver = (Driver) clazz.newInstance();
                Properties properties2 = new Properties();
                String user = (String) properties.get(EConnectivityProperties.PROP_ID_USER.getPropId());
                if (user != null) {
                    properties2.setProperty("user", user); //$NON-NLS-1$
                    String pwd = (String) properties.get(EConnectivityProperties.PROP_ID_PASSWORD.getPropId());
                    properties2.setProperty("password", pwd == null ? "" : pwd); //$NON-NLS-1$ //$NON-NLS-2$
                }
                String url = (String) properties.get(EConnectivityProperties.PROP_ID_URL.getPropId());
                connection = driver.connect(url, properties2);
            }
        } catch (Exception ex) {
            ExceptionOperation.openErrorDilogWithDetail(new Shell(), "Connection Error", ex.getMessage());
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getConnection".
     * 
     * @param shell
     * @param properties
     */
    public static void testConnection(Shell shell, final Properties properties) {
        ProgressMonitorDialog pmd = new ProgressMonitorDialog(shell);
        try {
            pmd.run(true, true, new IRunnableWithProgress() {

                public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    try {
                        monitor.beginTask(Messages.getString("ConnectivityDialog.startConn"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
                        final IDesignerCoreService designerCoreService = CorePlugin.getDefault().getDesignerCoreService();
                        final IXMLComponent component = designerCoreService.getComponentsFactory().getComponent(
                                GlobalComponentNames.ZTESTCONNECTION.getName());
                        final Process process = designerCoreService.launchShadowProcess(component, properties);
                        if (process == null) {
                            return;
                        }
                        final StringBuilder builder = new StringBuilder();
                        while (true) {
                            int read = 0;
                            byte[] bytes = new byte[8192];
                            if (process.getInputStream().available() > 0) {
                                BufferedInputStream stream = new BufferedInputStream(process.getInputStream(), 8192);
                                while (read >= 0) {
                                    read = stream.read(bytes);
                                    if (read > 0) {
                                        builder.append(new String(bytes, 0, read));
                                    }
                                }
                                break;
                            }
                            if (process.getErrorStream().available() > 0) {
                                BufferedInputStream stream = new BufferedInputStream(process.getErrorStream(), 8192);
                                while (read >= 0) {
                                    read = stream.read(bytes);
                                    if (read > 0) {
                                        builder.append(new String(bytes, 0, read));
                                    }
                                }
                                break;
                            }
                            if (monitor.isCanceled()) {
                                return;
                            }
                            Thread.sleep(100);
                        }

                        if (!monitor.isCanceled()) {
                            Display.getDefault().asyncExec(new Runnable() {

                                public void run() {
                                    MessageDialog.openInformation(new Shell(),
                                            Messages.getString("ConnectivityDialog.testConn"), builder.toString());//$NON-NLS-1$
                                }
                            });
                        }
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            });
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getConnection".
     * 
     * @return
     */
    public static Connection getConnection() {
        return connection;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "setConnection".
     * 
     * @param connection
     */
    public static void setConnection(Connection connection) {
        ConnectivityManager.connection = connection;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "closeConnection".
     */
    public static void closeConnection() {
        if (connection != null) {
            try {
                boolean b = connection.isClosed();
                if (!b) {
                    connection.close();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
        connection = null;
        schema = null;
    }

    /**
     * Getter for schema.
     * 
     * @return the schema
     */
    public static String getSchema() {
        return schema;
    }
}
